import  requests
import time
from multiprocessing import  Process
import  matplotlib.pyplot as plt
from threading import  Thread
import  threading
import  datetime
import  numpy as np
import  json

class OlapThread(Thread):
	def __init__(self,func,args=()):
		'''
		:param func: 被测试的函数
		:param args: 被测试的函数的返回值
		'''
		super(OlapThread,self).__init__()
		self.func=func
		self.args=args

	def run(self) -> None:
		self.result=self.func(*self.args)

	def getResult(self):
		try:
			return self.result
		except BaseException as e:
			return e.args[0]

def submitOlapSql(code,seconds,text,method,data,url,headers):
	'''
	:param code: 协议状态码
	:param seconds: 请求响应时间
	:param text: 响应内容
	:param method:请求方法
	:param data: 请求参数
	:param url: 请求地址
	:param headers：请求头
	:return:
	'''

	r=requests.request(
		method=method,
		url=url,
		json=data,
		timeout=960,
		headers=headers)
	print('输出信息昨状态码:{0},响应结果:{1}'.format(r.status_code,r.text))
	code=r.status_code
	seconds=r.elapsed.total_seconds()
	text=r.text
	return code,seconds,text

def calculationTime(startTime,endTime):
	'''计算两个时间之差，单位是秒'''
	return (endTime-startTime).seconds

def getResult(seconds):
	'''获取服务端的响应时间信息'''
	data={
		'Max':sorted(seconds)[-1],
		'Min':sorted(seconds)[0],
		'Median':np.median(seconds),
		'99%Line':np.percentile(seconds,99),
		'95%Line':np.percentile(seconds,95),
		'90%Line':np.percentile(seconds,90)
	}
	return data


def show(i,j):
	'''
	:param i: 请求总数
	:param j: 请求响应时间列表
	:return:
	'''
	fig,ax=plt.subplots()
	# ax.plot(list_count,seconds)
	ax.set(xlabel='number of times', ylabel='Request time-consuming',
	       title='olap continuous request response time (seconds)')
	ax.grid()
	fig.savefig('olap.png')
	plt.show()


def highConcurrent(count,method,data,url,headers):
	'''
	对服务端发送高并发的请求
	:param count: 并发用户数
	:param method：请求方法
	:param data: 请求参数
	:param url: 请求地址
	:param headers：请求头
	:return:
	'''
	startTime=datetime.datetime.now()
	sum=0
	list_count=list()
	tasks=list()
	results = list()
	#失败的信息
	fails=[]
	#成功任务数
	success=[]
	codes = list()
	seconds = list()
	texts=[]

	for i in range(0,count):
		t=OlapThread(submitOlapSql,args=(i,i,i,method,data,url,headers))
		tasks.append(t)
		t.start()
		print('测试中:{0}'.format(i))

	for t in tasks:
		t.join()
		if t.getResult()[0]!=200:
			fails.append(t.getResult())
		results.append(t.getResult())

	for item in fails:
		print('请求失败的信息:\n',item[2])
	endTime=datetime.datetime.now()
	for item in results:
		codes.append(item[0])
		seconds.append(item[1])
		texts.append(item[2])
	for i in range(len(codes)):
		list_count.append(i)

	#生成可视化的趋势图
	fig,ax=plt.subplots()
	ax.plot(list_count,seconds)
	ax.set(xlabel='number of times', ylabel='Request time-consuming',
	       title='olap continuous request response time (seconds)')
	ax.grid()
	fig.savefig('olap.png')
	plt.show()

	for i in seconds:
		sum+=i
	rate=sum/len(list_count)
	# print('\n总共持续时间:\n',endTime-startTime)
	totalTime=calculationTime(startTime=startTime,endTime=endTime)
	if totalTime<1:
		totalTime=1
	#吞吐量的计算
	try:
		throughput=int(len(list_count)/totalTime)
	except Exception as e:
		print(e.args[0])
	getResult(seconds=seconds)
	errorRate=0
	if len(fails)==0:
		errorRate=0.00
	else:
		errorRate=len(fails)/len(tasks)*100
	throughput=str(throughput)+'/S'
	timeData=getResult(seconds=seconds)
	# print('总耗时时间:',(endTime-startTime))
	timeConsuming=(endTime-startTime)
	return timeConsuming,throughput,rate,timeData,errorRate,len(list_count),len(fails)

if __name__ == '__main__':
	timeConsuming,throughput,rate,timeData,errorRate,sum,fails=highConcurrent(
		count=20,
		method='get',
		url='http://127.0.0.1:5000/login',
		data='',
		headers='')
	print('执行总耗时:',timeConsuming)
	data={'status':0,'msg': '请求成功','datas':
		[{
			'吞吐量':throughput,
			'平均响应时间':rate,
			'响应时间信息':timeData,
			'错误率':errorRate,
			'请求总数':sum,
			'失败数':fails
		}]}
	print(json.dumps(data,indent=True,ensure_ascii=False))

